package util
import (
	"database/sql"
	"github.com/tealeg/xlsx"
	"log"
	"strconv"
	"crypto/md5"
	"encoding/hex"
	"github.com/ant0ine/go-json-rest/rest"
//	"github.com/oleiade/reflections"
	"net/url"
	"encoding/json"
	//"github.com/djimenez/iconv-go"
	//"github.com/djimenez/iconv-go"
)

import(
	"crypto/rand"
	"encoding/base64"
	"io"
	"rocks/cfg"
	"fmt"
	"github.com/siddontang/ledisdb/ledis"
	lediscfg "github.com/siddontang/ledisdb/config"

)

func Log(v ...interface{}){

	if *cfg.Debug{
		log.Println(v...)
	}
}
//http://misc.flogisoft.com/bash/tip_colors_and_formatting
func LogGreen(v ...interface{}){
	str:=fmt.Sprint(v...)
	log.Printf("\033[1;32m%s\033[0m",str)
}
func LogRed(v ...interface{}){
	str:=fmt.Sprint(v...)
	log.Printf("\033[31m%s\033[0m",str)
}

func LogGray(v ...interface{}){
	if *cfg.Debug{
		str:=fmt.Sprint(v...)
		log.Printf("\033[90m%s\033[0m",str)
	}
}

func DecodeJsonQuery(v interface{}, url *url.URL) error {
	content := url.Query().Get("q");
	if len(content) > 0 {
		return json.Unmarshal([]byte(content), v)
	}
	return nil
}

func MarshalBs(data interface{})([]byte){
	bs, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}
	return bs
}

func GetMd5String(s string) string {
	h := md5.New()
	h.Write([]byte(s))
	return hex.EncodeToString(h.Sum(nil))
}

//生成Guid字串
func GetGuid() string {
	b := make([]byte, 48)
	if _, err := io.ReadFull(rand.Reader, b); err != nil {
		return ""
	}
	return GetMd5String(base64.URLEncoding.EncodeToString(b))
}


func GetUserName(r *rest.Request) (string) {
	return r.Env["REMOTE_USER"].(string)
}

//func JsonNormalize(v interface{} ) map[string]interface{}{
//	res:= map[string]interface{}{};
//	for _,v:=range *v{
//		idValue,err:=reflections.GetField(v,"Id")
//		if err!=nil{
//			log.Println(err)
//		}
//		res[idValue.(string)]=v;
//	}
//	return res
//}
func AddSheetData(xfile *xlsx.File, sheetName string, rows *sql.Rows, rcount int) {
	var fillterStr []string = []string{"-1.000", "0"}
	sheet := xfile.Sheet[sheetName]
	if sheet == nil {
		sheet, _ = xfile.AddSheet(sheetName)
	}
	cnames, _ := rows.Columns()
	ccount := len(cnames)
	log.Println("初始化单元格", sheetName, rcount, ccount)
	for i := 0; i < rcount + 10; i++ {
		r := sheet.AddRow()
		for j := 0; j < len(cnames); j++ {
			r.AddCell()
		}
	}
	for cidx, cname := range cnames {
		sheet.Cell(0, cidx).Value = cname
	}
	//添加数据
	log.Println("添加数据")

	colVals := make([]interface{}, ccount)
	colPtrs := make([]interface{}, ccount)
	for i := 0; i < len(colVals); i++ {
		colPtrs[i] = &colVals[i]
	}
	rowindex := 1
	for rows.Next() {
		rows.Scan(colPtrs...)
		for i, v := range colVals {
			tv := ""
			if v != nil {
				//				fmt.Println(reflect.ValueOf(v).Type(),reflect.ValueOf(v).Kind())
				switch  v.(type) {
				case []byte:
					//					tv= strings.Replace(string(v.([]byte)),"\\","\\\\",-1)
					tv = string(v.([]byte))
				case int64:
					tv = strconv.FormatInt(v.(int64), 10)
				case float32:
				case float64:
					tv = strconv.FormatFloat(v.(float64), 'f', 3, 32)
				}
				for _, v := range fillterStr {
					if tv == v {tv = ""; break}
				}
				sheet.Cell(rowindex, i).Value = string(tv)
			}
		}
		rowindex++
	}
	log.Println("添加数据完成", sheetName)
}

/*var encodingConverter, _ = iconv.NewConverter("utf-8", "gb2312")
func ChineseSpellPre(strText string) string {
	myStr := "";
	for _, str := range strText {
		output, err := encodingConverter.ConvertString(string(str))
		if err != nil {log.Println(err)}
//			log.Println("iconvert ",string(str),int32(str),strconv.FormatInt(int64(str),16),len([]rune(output)),output)
		myStr += getSpell([]byte(output))
	}
	return myStr;
}*/
func getSpell(bs []byte) string {
	if len(bs) > 1 {
		area := int32(bs[0])
		pos := int32(bs[1]);
		var code int32 = (area << 8) + pos;
		log.Print(code)
//		log.Println("str:", code,string(bs))
		if code > 256 {
			var nextCode int32 = 0
			areacode := []int32{45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481, 55290 };
			for i := range areacode {
				if i < 26 {
					nextCode = areacode[i + 1]
				}else {
					nextCode = 55290
				}

				if areacode[i] <= code && code < nextCode {
					return string(rune(65 + i))
				}
			}

		}else {
			return string(bs); }
	}else{
		return string(bs);
	}
	return "*"

}

var Ldb *ledis.DB

func init(){

	lcfg := lediscfg.NewConfigDefault()
	lcfg.DBName="rocksdb"
	//cfg.DBName="goleveldb"
	lcfg.Databases=16
	lcfg.DataDir=*cfg.DataDir
	l, err := ledis.Open(lcfg)

	if err!=nil{
		panic(err)
		return
	}
	if err==nil {
		ldb, err1 := l.Select(0)
		err=err1
		Ldb = ldb
	}
	if err!=nil{
		panic(err)
		return
	}

}
